"""
build_lib_switch.py
Copyright 2015 Adam Greig
Licensed under the MIT licence, see LICENSE file for details.

Generate switch.lib, generic nPmT switch symbols.
"""

from __future__ import print_function, division
import sys
import os.path


def switch(n, m):
    """
    Generates a generic switch symbol for an nPsT sort of switch.
    Probably won't generate a useful pin numbering when T>2.
    """
    out = []

    # Convert to stupid letters for 1 and 2
    name_letters = {1: "S", 2: "D"}
    name_n = name_letters[n] if n in name_letters else str(n)
    name_m = name_letters[m] if m in name_letters else str(m)

    # Number of pins on the right is n*m, plus one per pole for spacing,
    # minus the final spacing (n starts at 1), rounded up to nearest odd
    # number so that half the height is on the 100mil grid.
    n_pins_right = n * m + n - 1
    if n_pins_right % 2 == 0:
        n_pins_right += 1
    height = 100 * (n_pins_right - 1)
    hheight = height // 2

    # Ref goes at the top, 100 above the top pin, unless only one throw
    # in which case we also need to clear the switch graphic
    refheight = hheight + 100
    if m == 1:
        refheight += 50

    # Value/name goes below, unless m is even, in which case the bottom spacer
    # isn't there so needs to be ignored
    valheight = -(hheight + 100)
    if n % 2 == 1 and m % 2 == 0:
        valheight += 100

    # Output component header
    name = "SWITCH_{}P{}T".format(name_n, name_m)
    out.append("#\n# {}\n#".format(name))
    out.append('DEF {} SW 0 1 Y N 1 F N'.format(name))
    out.append('F0 "SW" 0 {} 50 H V C CNN'.format(refheight))
    out.append('F1 "{}" 0 {} 50 H V C CNN'.format(name, valheight))
    out.append('F2 "" 0 0 50 H I C CNN')
    out.append('F3 "" 0 0 50 H I C CNN')
    out.append('DRAW')

    # Output drawing
    pole_top = hheight
    for pole in range(n):
        # Draw pole
        pole_num = pole*(m+1) + 2
        pole_y = pole_top - (100 * (m - 1))//2
        if m % 2 == 0:
            pole_y -= 50
        out.append('X "~" {} -100 {} 40 R 50 50 1 1 P'
                   .format(pole_num, pole_y))
        out.append('C -50 {} 10 1 1 0 N'.format(pole_y))
        out.append('P 2 1 1 0 -50 {} 50 {} N'
                   .format(pole_y + 10, pole_y + 90))

        for throw in range(m):
            # Draw throws
            throw_num = pole_num + throw - 1
            throw_y = pole_top - 100 * throw
            if throw > 0:
                throw_num += 1
            out.append('X "~" {} 100 {} 40 L 50 50 1 1 P'
                       .format(throw_num, throw_y))
            out.append('C 50 {} 10 1 1 0 N'.format(throw_y))

        # Move down for next pole
        pole_top -= 100 * (m + 1)

    # Draw connecting dashed line
    if n > 1:
        pole_y = hheight - (100 * (m - 1))//2 + 50
        if m % 2 == 0:
            pole_y -= 50
        for _ in range(5*(m+1)*(n-1)):
            out.append('P 2 1 1 0 0 {} 0 {} N'
                       .format(pole_y, pole_y - 5))
            pole_y -= 20

    # Done
    out.append('ENDDRAW\nENDDEF\n')

    return out


def main(libpath, verify=False):
    out = []
    out.append("EESchema-LIBRARY Version 2.3")
    out.append("#encoding utf-8\n")
    out.append("#============================================================")
    out.append("# Automatically generated by agg-kicad build_lib_switch.py")
    out.append("# See github.com/adamgreig/agg-kicad")
    out.append("#============================================================")
    out.append("")

    for n in (1, 2, 3):
        for m in (1, 2, 3):
            out += switch(n, m)

    out.append('# End Library\n')
    lib = "\n".join(out)

    # Check if the library has changed
    if os.path.isfile(libpath):
        with open(libpath) as f:
            oldlib = f.read()
            if lib == oldlib:
                return True

    # If so, validation has failed or update the library file
    if verify:
        return False
    else:
        with open(libpath, "w") as f:
            f.write(lib)


if __name__ == "__main__":
    if len(sys.argv) == 2:
        main(sys.argv[1])
    elif len(sys.argv) == 3 and sys.argv[2] == "--verify":
        if main(sys.argv[1], verify=True):
            print("OK: lib up-to-date.")
            sys.exit(0)
        else:
            print("Error: lib not up-to-date.", file=sys.stderr)
            sys.exit(1)
    else:
        print("Usage: {} <lib path> [--verify]".format(sys.argv[0]))
        sys.exit(1)
